/*
 * Copyright (C) 2022 ByteDance Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bytedance.danmaku.render.engine.data

import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.annotation.UiThread
import com.bytedance.danmaku.render.engine.control.DanmakuConfig
import com.bytedance.danmaku.render.engine.control.DanmakuController
import com.bytedance.danmaku.render.engine.render.cache.LayerBuffer
import com.bytedance.danmaku.render.engine.render.draw.text.TextData
import java.sql.Time
import java.util.*
import kotlin.math.max

/**
 * Created by dss886 on 2018/11/6.
 * DataManager is the timeline controller for the danmakus
 */
class DataManager(controller: DanmakuController) {

    private val mList = LinkedList<DanmakuData>()
    var mQueryList = LinkedList<DanmakuData>()
    /**
     * Fake items will be added to the return list in [queryDanmaku] immediately.
     * Even so, there is no guarantee that them will be displayed 100%,
     * as the render layers will discard data when the amount of data is too large.
     * See [LayerBuffer]
     */
    private val mFakeList = LinkedList<DanmakuData>()
    private val mConfig: DanmakuConfig = controller.config

    private var mIsPlaying = false
    private var mCurrentIndex = 0
    private var mStartPlayTime = 0L
    private var mStartTimestamp = 0L
    var mCurrentPlayTime = 0L
    var Time=0L
    @UiThread
    fun setData(dataList: List<DanmakuData>) {
        mList.clear()
        mList.addAll(dataList)
    }

    @UiThread
    fun appendData(dataList: List<DanmakuData>) {
        mList.addAll(dataList)
    }

    @UiThread
    fun addFakeData(data: DanmakuData) {
        mFakeList.add(data)
    }


    fun getData() : List<DanmakuData>{
        return mList
    }
    fun getQureyData():List<DanmakuData>
    {
        return mQueryList
    }


    @UiThread
    fun onPlay(playTime: Long) {
        mIsPlaying = true
        mCurrentIndex = 0
        mStartPlayTime = max(0, playTime)
        mStartTimestamp = System.currentTimeMillis()
        mCurrentPlayTime = mStartPlayTime
        mList.forEachIndexed { index, danmaku ->
            if (danmaku.showAtTime >= playTime) {
                return
            }
            mCurrentIndex = index + 1
        }
    }
    @RequiresApi(Build.VERSION_CODES.N)
    fun filterData(time:Long){
//        mList.removeIf {
//            time-it.showAtTime > 1000 }
//        Log.e("库移除后数据","${mList.size}")
    }
    @UiThread
    fun onPlaySpeedChanged() {
        mStartPlayTime = mCurrentPlayTime
        mStartTimestamp = System.currentTimeMillis()
    }

    @UiThread
    fun queryPlayTime(): Long {
        if (!mIsPlaying) {
            return mCurrentPlayTime
        }
        val now = System.currentTimeMillis()
        val playTime = ((now - mStartTimestamp) * mConfig.common.playSpeed / 100f + mStartPlayTime).toLong()
        mCurrentPlayTime = playTime
        return mCurrentPlayTime
    }
    @UiThread
    fun queryDanmaku(): List<DanmakuData> {
        if (!mIsPlaying) {
            return mQueryList.apply { clear() }
        }
        mQueryList.clear()
        mQueryList.addAll(mFakeList)
        mFakeList.clear()

        // 1. 先加载当前时间窗口内的所有弹幕（基础筛选）
        while (true) {
            if (mCurrentIndex < 0 || mCurrentIndex >= mList.size) break
            val item = mList[mCurrentIndex]
//            if (item.showAtTime > mCurrentPlayTime) break
            if (item.showAtTime > mCurrentPlayTime) break
            mQueryList.add(item)
            mCurrentIndex++
        }

        // 2. 按“秒级时间”分组，同一秒内按长度筛选数量
        val filteredList = filterDanmakuBySecondAndLength(mQueryList)
        mQueryList.clear()
        mQueryList.addAll(filteredList)

        return mQueryList
    }
    /**
     * 按秒级时间分组，同一秒内根据长度限制数量：
     * - 长度>8的弹幕保留3条
     * - 长度≤8的弹幕保留4条
     */
    private fun filterDanmakuBySecondAndLength(rawList: List<DanmakuData>): List<DanmakuData> {
        // 按“秒”分组（showAtTime转换为秒级时间戳）
        val groupBySecond = rawList.groupBy { it.showAtTime / 1000 }

        val result = mutableListOf<DanmakuData>()
        groupBySecond.forEach { (_, secondDanmakus) ->
            // 按长度分类：长弹幕（>8）和短弹幕（≤8）
            val longDanmakus = secondDanmakus.filter { it.getContentLength()!! > 8 }
            val shortDanmakus = secondDanmakus.filter { it.getContentLength()!! <= 8 }

            // 限制数量：长弹幕保留前3条，短弹幕保留前4条（可根据需求调整保留策略，如按优先级）
            result.addAll(longDanmakus.take(2))
            result.addAll(shortDanmakus.take(4))
        }
        return result
    }
    /**
     * 扩展方法：获取弹幕内容长度（假设DanmakuData有text字段，需根据实际类型调整）
     */
    private fun DanmakuData.getContentLength(): Int? {
        return when (this) {
            is TextData -> this.text?.length?:0 // 假设TextData是实际使用的弹幕数据类型
            else -> 0 // 其他类型（如图片弹幕）可自定义长度计算
        }
    }
//    @UiThread
//    fun queryDanmaku(): List<DanmakuData> {
//        if (!mIsPlaying) {
//            return mQueryList.apply { clear() }
//        }
//        mQueryList.clear()
//        mQueryList.addAll(mFakeList)
//        mFakeList.clear()
//        while (true) {
//            if (mCurrentIndex < 0 || mCurrentIndex >= mList.size) {
//                break
//            }
//            val item = mList[mCurrentIndex]
//            if (item.showAtTime > mCurrentPlayTime) {
//                break
//            }
//            mQueryList.add(item)
//            mCurrentIndex++
//        }
//        return mQueryList
//    }

    @UiThread
    fun getRemainDanmakuCount(): Int {
        return mList.size - mCurrentIndex
    }

    @UiThread
    fun nextDanmakuShowAfter(): Long {
        return if (mList.size > 0 && mCurrentIndex < mList.size) {
            mList[mCurrentIndex].showAtTime - mCurrentPlayTime
        } else {
            -1
        }
    }

    @UiThread
    fun onPause() {
        mIsPlaying = false
    }

    @UiThread
    fun onStop() {
        mIsPlaying = false
        mList.clear()
        mQueryList.clear()
        mFakeList.clear()
        mCurrentIndex = 0
        mStartPlayTime = 0L
        mStartTimestamp = 0L
        mCurrentPlayTime = 0L
    }

}
